<template>
  <div class="chat-container">
    <div class="chat-header">
      <h2>AI 助手</h2>
    </div>
    <div ref="messagesContainer" class="chat-messages">
      <div
          v-for="(msg, index) in messages"
          :key="msg.id"
          class="message"
          :class="{'user-message': msg.role === 'user', 'ai-message': msg.role === 'assistant'}"
      >
        <el-avatar class="avatar" :src="msg.role === 'user' ? userAvatar : aiAvatar"/>
        <div class="message-content">
          <div class="message-text">
            <span v-if="msg.isStreaming" class="streaming-indicator"></span>
            <!-- 显示文件消息 -->
            <template v-if="msg.content_type === 'file'">
              <div class="file-message">
                <i class="el-icon-document"></i>
                <div class="file-info">
                  <div class="file-name">{{ msg.file_name }}</div>
                  <div class="file-size">{{ formatFileSize(msg.file_size) }}</div>
                </div>
              </div>
            </template>
            <!-- AI消息支持Markdown渲染 -->
            <template v-else-if="msg.role === 'assistant'">
              <div class="markdown-content" v-html="renderMarkdown(msg.content)"></div>
            </template>
            <!-- 用户消息纯文本显示 -->
            <template v-else>
              {{ msg.content }}
            </template>
          </div>
          <!-- 显示关联问题 -->
          <div v-if="msg.followUpQuestions && msg.followUpQuestions.length">
            <div class="question_or">或许您还想问：</div>
            <div
                v-for="question in msg.followUpQuestions"
                :key="question"
                class="follow-up-question"
                @click="sendFollowUpQuestion(question)"
            >{{ question }}
            </div>
          </div>
          <div class="message-time">{{ formatTime(msg.timestamp) }}</div>
        </div>
      </div>
    </div>

    <!-- 文件上传区域 -->
    <div class="file-upload-container">
      <div class="file-upload-area">
        <label class="upload-label" :class="{ 'upload-disabled': isLoading || isUploading }" v-if="!isUploading">
          <i class="el-icon-upload2"></i>
          <span>知识库：拖拽文件到此处或点击上传</span>
          <input
              type="file"
              class="file-input"
              @change="handleFileSelected"
              :disabled="isLoading || isUploading"
          >
          <div class="supported-formats">支持 PDF, DOC, DOCX, TXT 等格式</div>
        </label>

        <!-- 上传进度显示区域 -->
        <div class="upload-progress-area" v-if="isUploading">
          <div class="progress-info">
            <i class="el-icon-loading"></i>
            <span>正在上传：{{ uploadingFileName }}</span>
          </div>
          <el-progress
              :percentage="uploadProgress"
              stroke-width="3"
              style="margin-top: 10px;"
          ></el-progress>
          <div class="progress-text">{{ uploadProgress }}% - {{ formatFileSize(uploadedBytes) }} / {{ formatFileSize(totalFileSize) }}</div>
        </div>
      </div>
    </div>

    <div class="chat-input">
      <el-input
          v-model="inputMessage"
          placeholder="输入消息..."
          @keyup.enter="sendMessage"
          class="input-box"
          :disabled="isLoading || isUploading"
      >
        <template #append>
          <el-button
              type="primary"
              icon="el-icon-s-promotion"
              class="send-button"
              :loading="isLoading || isUploading"
              @click="sendMessage"
          >发送</el-button>
        </template>
      </el-input>
    </div>
  </div>
</template>

<script setup>
import {ref, computed, onMounted, nextTick} from 'vue'
import {useUserStore} from "../stores/user.js";
import {CozeAPI} from '@coze/api';
import {ElMessage} from 'element-plus';
import {marked} from 'marked';

// 基础Markdown配置（禁用代码高亮相关配置）
marked.setOptions({
  breaks: true, // 支持换行
  gfm: true, // 支持GitHub Flavored Markdown
  mangle: false, // 不混淆邮箱
  headerIds: false // 不生成标题ID
});

// 用户状态
const userStore = useUserStore()
const userInfo = computed(() => userStore.userInfo)

// 消息数据
const messages = ref([
  {
    id: Date.now(),
    role: 'assistant',
    content: '你好！我是AI助手',
    content_type: 'text',
    timestamp: new Date(),
    isStreaming: false,
    followUpQuestions: []
  }
])

// 引用消息容器
const messagesContainer = ref(null)

// AI 头像
const aiAvatar = ref('https://img0.baidu.com/it/u=2071933961,4247210309&fm=253&app=138&f=JPEG?w=800&h=800')
const userAvatar = ref('https://img1.baidu.com/it/u=2897073946,1539786358&fm=253&app=138&f=JPEG?w=800&h=800')

// 输入消息
const inputMessage = ref('')
const isLoading = ref(false)
const isUploading = ref(false)
const uploadProgress = ref(0)
const uploadedBytes = ref(0)
const totalFileSize = ref(0)
const uploadingFileName = ref('')

// Coze API 客户端
const cozeApiClient = ref(null)
const knowledgeApiAuthToken = 'sat_iDrvlLhEuuSIp8aiyw9l8aP9FpiN1r3YKepBdFR8bSLpTN9KkxFszZihZ7DwZBTk'

// 初始化Coze API客户端
const initCozeApiClient = () => {
  cozeApiClient.value = new CozeAPI({
    token: "sat_iDrvlLhEuuSIp8aiyw9l8aP9FpiN1r3YKepBdFR8bSLpTN9KkxFszZihZ7DwZBTk",
    baseURL: "https://api.coze.cn"
  })
}

// 格式化时间
const formatTime = (date) => {
  return new Date(date).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'})
}

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 滚动到底部
const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
    }
  })
}

// Markdown渲染方法
const renderMarkdown = (content) => {
  if (!content) return ''
  return marked.parse(content)
}

// 发送消息
const sendMessage = async () => {
  if (!inputMessage.value.trim() || isLoading.value || isUploading.value) return

  // 添加用户消息
  const userMessage = {
    id: Date.now(),
    role: 'user',
    content_type: 'text',
    content: inputMessage.value,
    timestamp: new Date(),
    isStreaming: false
  }
  messages.value.push(userMessage)

  // 添加初始AI消息
  const aiMessageId = Date.now() + 1
  const aiMessage = {
    id: aiMessageId,
    role: 'assistant',
    content: '',
    timestamp: new Date(),
    isStreaming: true,
    followUpQuestions: []
  }
  messages.value.push(aiMessage)

  // 保存消息内容
  const currentInput = inputMessage.value
  inputMessage.value = ''
  isLoading.value = true

  // 滚动到底部
  scrollToBottom()

  try {
    // 准备历史消息
    const historyMessages = messages.value
        .filter(msg => msg.id !== aiMessageId)
        .map(msg => ({
          role: msg.role,
          content: msg.content,
          content_type: msg.content_type,
          type: msg.role === 'user' ? 'question' : 'answer'
        }))

    // 使用Coze SDK的流式API
    const stream = await cozeApiClient.value.chat.stream({
      bot_id: '7525712099474423846',
      user_id: '123456789',
      additional_messages: historyMessages
    })
    const aiMessageIndex = messages.value.findIndex(msg => msg.id === aiMessageId);
    if (aiMessageIndex === -1) return

    // 处理流式响应
    for await (const chunk of stream) {
      if (chunk.event === 'conversation.message.delta' && chunk.data.content) {
        if (aiMessageIndex !== -1) {
          messages.value[aiMessageIndex].content += chunk.data.content;
          messages.value = [...messages.value];
          scrollToBottom();
        }
      }
      // 处理关联问题
      if (chunk.event === 'conversation.message.completed' && chunk.data.follow_up_questions) {
        const aiMessageIndex = messages.value.findIndex(msg => msg.id === aiMessageId)
        if (aiMessageIndex !== -1) {
          messages.value[aiMessageIndex].followUpQuestions = chunk.data.follow_up_questions
        }
      }
    }

  } catch (error) {
    console.error('API请求错误:', error)
    const aiMessageIndex = messages.value.findIndex(msg => msg.id === aiMessageId)
    if (aiMessageIndex !== -1) {
      messages.value[aiMessageIndex].content = '抱歉，处理您的请求时出错了。请稍后再试。'
    }
  } finally {
    const aiMessageIndex = messages.value.findIndex(msg => msg.id === aiMessageId)
    if (aiMessageIndex !== -1) {
      messages.value[aiMessageIndex].isStreaming = false
      messages.value[aiMessageIndex].timestamp = new Date()
    }

    isLoading.value = false
    scrollToBottom()
  }
}

// 发送关联问题
const sendFollowUpQuestion = (question) => {
  inputMessage.value = question;
  nextTick(() => {
    sendMessage();
  });
}

// 处理文件选择
const handleFileSelected = async (event) => {
  const file = event.target.files[0]
  if (!file) return

  // 清空input值
  event.target.value = ''

  // 初始化上传状态
  isUploading.value = true
  uploadProgress.value = 0
  uploadedBytes.value = 0
  totalFileSize.value = file.size
  uploadingFileName.value = file.name

  // 创建文件消息
  const fileMessageId = Date.now()
  const fileMessage = {
    id: fileMessageId,
    role: 'user',
    content_type: 'file',
    content: '',
    file_name: file.name,
    file_size: file.size,
    timestamp: new Date()
  }
  // messages.value.push(fileMessage)
  // scrollToBottom()

  try {
    // 读取文件为Base64
    const base64Content = await readFileAsBase64(file)

    // 创建知识文档
    await createKnowledgeDocumentWithBase64(file, base64Content)

    // 显示成功提示
    ElMessage.success({
      message: `文件 ${file.name} 上传成功并已添加到知识库`,
      duration: 3000,
      showClose: true
    })

    // 自动发送消息
    // inputMessage.value = `我已上传文件: ${file.name}，请基于此文件内容为我解答问题`
    // nextTick(() => {
    //   sendMessage()
    // })
  } catch (error) {
    console.error('文件上传失败:', error)
    ElMessage.error({
      message: `文件上传失败: ${error.message || '未知错误'}`,
      duration: 5000,
      showClose: true
    })
  } finally {
    // 重置上传状态
    isUploading.value = false
    uploadProgress.value = 0
    uploadedBytes.value = 0
    totalFileSize.value = 0
    uploadingFileName.value = ''
    scrollToBottom()
  }
}

// 读取文件为Base64
const readFileAsBase64 = (file) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()

    reader.onload = (event) => {
      const base64String = event.target.result.split(',')[1]
      resolve(base64String)
    }

    reader.onerror = (error) => {
      reject(new Error(`读取文件失败: ${error.message}`))
    }

    // 监听读取进度
    reader.onprogress = (event) => {
      if (event.lengthComputable) {
        const percent = Math.round((event.loaded / event.total) * 100)
        uploadProgress.value = percent
        uploadedBytes.value = event.loaded
      }
    }

    reader.readAsDataURL(file)
  })
}

// 创建知识文档
const createKnowledgeDocumentWithBase64 = async (file, base64Content) => {
  try {
    const response = await fetch('https://api.coze.cn/open_api/knowledge/document/create', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${knowledgeApiAuthToken}`,
        'Content-Type': 'application/json',
        'Agw-Js-Conv': 'str'
      },
      body: JSON.stringify({
        "dataset_id": "7525378181591908403",
        "document_bases": [
          {
            "name": file.name,
            "source_info": {
              "document_source": 0,
              "file_type": getFileExtension(file.name),
              "file_base64": base64Content
            }
          }
        ],
        "chunk_strategy": {
          "max_tokens": 800,
          "chunk_type": 0,
          "remove_extra_spaces": true,
          "remove_urls_emails": true,
          "caption_type": 0
        },
        "format_type": 0
      })
    })

    const result = await response.json()

    if (!response.ok || (result.code !== 0 && result.code !== undefined)) {
      throw new Error(`创建知识文档失败: ${result.msg || '未知错误'}`)
    }

    return result
  } catch (error) {
    console.error('创建知识文档API调用失败:', error)
    throw error
  }
}

// 获取文件扩展名
const getFileExtension = (filename) => {
  return filename.split('.').pop().toLowerCase() || ''
}

// 页面加载时初始化
onMounted(() => {
  initCozeApiClient()
  scrollToBottom()
})
</script>

<style scoped>
/* 基础样式保持不变 */
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  max-width: 800px;
  margin: 0 auto;
  border: 1px solid #ebeef5;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.chat-header {
  padding: 15px 20px;
  background-color: #409eff;
  color: white;
  text-align: center;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background-color: #f5f7fa;
}

.message {
  display: flex;
  margin-bottom: 20px;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.user-message {
  flex-direction: row-reverse;
}

.avatar {
  flex-shrink: 0;
  margin: 0 10px;
  width: 40px;
  height: 40px;
}

.message-content {
  max-width: 70%;
  padding: 12px 16px;
  border-radius: 10px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  position: relative;
}

.user-message .message-content {
  background-color: #409eff;
  color: white;
  border-top-right-radius: 4px;
}

.ai-message .message-content {
  background-color: white;
  border: 1px solid #ebeef5;
  border-top-left-radius: 4px;
}

.message-text {
  word-break: break-word;
  white-space: pre-wrap;
}

/* Markdown渲染样式 */
.markdown-content {
  text-align: left;
}

/* 标题样式 */
.markdown-content h1 {
  font-size: 1.5em;
  margin: 0.8em 0 0.5em;
  font-weight: bold;
  color: #333;
  border-bottom: 1px solid #eee;
  padding-bottom: 0.3em;
}

.markdown-content h2 {
  font-size: 1.3em;
  margin: 0.7em 0 0.4em;
  font-weight: bold;
  color: #333;
  border-bottom: 1px solid #eee;
  padding-bottom: 0.2em;
}

.markdown-content h3 {
  font-size: 1.1em;
  margin: 0.6em 0 0.3em;
  font-weight: bold;
  color: #333;
}

/* 列表样式 */
.markdown-content ul,
.markdown-content ol {
  padding-left: 1.5em;
  margin: 0.5em 0;
}

.markdown-content ul {
  list-style-type: disc;
}

.markdown-content ol {
  list-style-type: decimal;
}

.markdown-content li {
  margin: 0.3em 0;
}

/* 强调样式 */
.markdown-content strong {
  font-weight: bold;
  color: #333;
}

.markdown-content em {
  font-style: italic;
  color: #666;
}

/* 链接样式 */
.markdown-content a {
  color: #409eff;
  text-decoration: underline;
}

.markdown-content a:hover {
  color: #66b1ff;
}

/* 引用样式 */
.markdown-content blockquote {
  border-left: 3px solid #409eff;
  padding-left: 10px;
  margin: 0.5em 0;
  color: #666;
  font-style: italic;
}

/* 代码块样式（基础样式，无高亮） */
.markdown-content pre {
  background-color: #f5f5f5;
  padding: 10px;
  border-radius: 4px;
  overflow-x: auto;
  margin: 0.5em 0;
  font-family: monospace;
  font-size: 0.9em;
}

.markdown-content code {
  background-color: #f5f5f5;
  padding: 2px 4px;
  border-radius: 2px;
  font-family: monospace;
  font-size: 0.9em;
}

/* 文件消息样式 */
.file-message {
  display: flex;
  align-items: center;
  gap: 10px;
}

.file-message .el-icon-document {
  font-size: 24px;
  color: #409eff;
}

.file-info {
  flex: 1;
}

.file-name {
  font-weight: 500;
  margin-bottom: 4px;
}

.file-size {
  font-size: 12px;
  opacity: 0.8;
}

.message-time {
  font-size: 12px;
  margin-top: 5px;
  opacity: 0.8;
}

.user-message .message-time {
  text-align: right;
  color: rgba(255, 255, 255, 0.8);
}

.ai-message .message-time {
  color: #909399;
}

/* 文件上传区域样式 */
.file-upload-container {
  border-top: 1px solid #ebeef5;
  border-bottom: 1px solid #ebeef5;
  background-color: #fafafa;
}

.file-upload-area {
  padding: 15px 20px;
  transition: all 0.3s ease;
}

.upload-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 25px 20px;
  border: 2px dashed #c0c4cc;
  border-radius: 8px;
  background-color: white;
  cursor: pointer;
  transition: all 0.3s ease;
  color: #606266;
  text-align: center;
}

.upload-label:hover {
  border-color: #409eff;
  color: #409eff;
  background-color: rgba(64, 158, 255, 0.05);
}

.upload-disabled {
  cursor: not-allowed;
  opacity: 0.7;
}

.upload-disabled:hover {
  border-color: #c0c4cc;
  color: #606266;
  background-color: white;
}

.upload-label .el-icon-upload2 {
  font-size: 28px;
  margin-bottom: 10px;
}

.supported-formats {
  font-size: 12px;
  margin-top: 8px;
  color: #909399;
}

.file-input {
  display: none;
}

/* 上传进度区域样式 */
.upload-progress-area {
  padding: 20px;
  background-color: white;
  border-radius: 8px;
  border: 1px solid #ebeef5;
}

.progress-info {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #606266;
}

.progress-info .el-icon-loading {
  animation: loading 1s infinite linear;
}

.progress-text {
  font-size: 12px;
  color: #909399;
  margin-top: 6px;
  text-align: right;
}

@keyframes loading {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.chat-input {
  padding: 15px;
  background-color: white;
  border-top: 1px solid #ebeef5;
}

.input-box {
  height: 50px;
}

/* 流式响应指示器 */
.streaming-indicator {
  display: inline-block;
  width: 8px;
  height: 8px;
  background-color: #409eff;
  border-radius: 50%;
  margin-right: 5px;
  animation: pulse 1.5s infinite;
}

.follow-up-question {
  margin-top: 5px;
  cursor: pointer;
  color: #70e4f3;
  text-decoration: underline;
  transition: color 0.2s;
}

.follow-up-question:hover {
  color: #409eff;
}

.question_or {
  color: #ff3369;
  margin-top: 8px;
  font-size: 13px;
  font-weight: 500;
}

@keyframes pulse {
  0% {
    opacity: 0.3;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0.3;
  }
}
</style>